
package com.gitee.jmash.oidc.client.web.models;

import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.mvc.RedirectScoped;
import jakarta.mvc.binding.BindingResult;
import jakarta.mvc.binding.ParamError;
import jakarta.validation.ConstraintViolation;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.velocity.tools.generic.ResourceTool;
import org.eclipse.krazo.binding.BindingErrorImpl;
import org.eclipse.krazo.binding.ValidationErrorImpl;

/**
 * Redirect .
 *
 * @author CGD
 *
 */
@Named
@RedirectScoped
public class RedirectResult implements Serializable {

  private static final long serialVersionUID = 1L;

  private boolean success = true;

  private List<String> messages = null;

  private Set<ParamError> errors = null;

  @Named("text")
  @Inject
  ResourceTool text;

  public RedirectResult() {
  }

  /** Add BindingResult. */
  public void addBindingResult(BindingResult result) {
    success = !result.isFailed();
    messages = result.getAllMessages();
    errors = result.getAllErrors();
  }

  /** Add ConstraintViolation Set. */
  public  void addConstraintViolationSet(Set<ConstraintViolation<?>> validResult) {
    success = (validResult.size() == 0);
    if (null == errors) {
      errors = new HashSet<>();
    }
    if (validResult.size() > 0) {
      validResult.stream().forEach(v -> errors
          .add(new ValidationErrorImpl(v, v.getPropertyPath().toString(), v.getMessage())));
    }
  }

  /** Add Param Message. */
  public void addError(String msgKey, String paramName) {
    success = false;
    if (null == errors) {
      errors = new HashSet<>();
    }
    String message = text.get(msgKey).toString();
    errors.add(new BindingErrorImpl(message, paramName, ""));
  }

  public boolean isSuccess() {
    return success;
  }

  public boolean isFailed() {
    return !success;
  }

  /** Get All Message. */
  public List<String> getAllMessages() {
    if (null == messages) {
      return Collections.emptyList();
    }
    return messages;
  }

  /** Get All Error. */
  public Set<ParamError> getAllErrors() {
    if (null == errors) {
      return Collections.emptySet();
    }
    return errors;
  }

  /** Get Param Error. */
  public Set<ParamError> getErrors(String param) {
    if (null == errors) {
      return Collections.emptySet();
    }
    return errors.stream().filter(paramError -> Objects.equals(paramError.getParamName(), param))
        .collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
  }

  /** Get Html Error. */
  public String getHtmlErrors() {
    if (null == errors) {
      return "";
    }
    StringBuilder builder = new StringBuilder();
    int i = 1;
    for (ParamError error : errors) {
      String paramNameTip = text.get(error.getParamName()).toString();
      builder.append((i++) + "." + paramNameTip + ":" + error.getMessage() + ";<br/>");
    }
    return builder.toString();
  }

}
